﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestByWire.Tutorial.Domain;

namespace TestByWire.Tutorial
{
    [TestClass]
    [UseStubLateBound(typeof(IContacts), "_contactManager", typeof(ContactManager))]
    public class LateBoundStubbing : TestTarget<CalendarApp>
    {
        [TestMethod]
		[ResetStub(typeof(IContacts), "_contactManager")]
        public void MustBeAbleToStubLateBound()
        {
            Given.That<IContacts>(c => c.GetContactName(0)).Returns("John Doe");

            When.Calling.ContactManager.GetContactName(10);

            Then<IContacts>.Should(c => c.GetContactName(10));
        }
    }

    [TestClass]
	[UseStubLateBound(typeof(IContacts), "_contactManager", typeof(ContactManager))]
    public class LateBoundStubbingVariant : TestTarget<CalendarApp2>
    {
        [TestMethod]
		[ResetStub(typeof(IContacts), "_contactManager")]
        public void MustBeAbleToStubLateBound()
        {
            Given.That<IContacts>(c => c.GetContactName(0)).Returns("John Doe");

            Assert.IsNull(When.Calling.ContactManager);
        }
    }

    public interface IContacts
    {
        string GetContactName(int contactId);
    }

    internal class ContactManager : IContacts
    {
        public string GetContactName(int contactId)
        {
            return "Hello World";
        }
    }

    public class CalendarApp
    {
        private readonly IContacts _contactManager;

        public CalendarApp(IContacts contactManager)
        {
            _contactManager = contactManager;
        }

        public IContacts ContactManager
        {
            get { return _contactManager; }
        }
    }

    public class CalendarApp2
    {
        private readonly IContacts _contactManager;

        public CalendarApp2()
        {
            _contactManager = null;
        }

        public IContacts ContactManager
        {
            get { return _contactManager; }
        }
    }
}
